#include "fileprocessworker.h"
#include "nextgen_placeholder.h"
#include "unifiedcachemanager.h"
#include "fileidentitymanager.h"
#include <QFileInfo>
#include <QImageReader>
#include <QDebug>
#include <QApplication>
#include <QThread>
#include <QImage>
#include <QSettings>
#include <QPainter>
#include <QDateTime>
#include <QFile>
#include <QTextStream>
#include <QStringConverter>
#include <cpp/poppler-document.h>
#include <cpp/poppler-page.h>
#include <cpp/poppler-page-renderer.h>
FileProcessWorker::FileProcessWorker(int fileIndex, const QString& filePath,
                                     const DpiConfiguration& dpiConfig, QObject* parent)
    : QObject(parent)
    , m_fileIndex(fileIndex)
    , m_filePath(filePath)
    , m_cancelled(false)
    , m_dpiConfig(dpiConfig)
{
    setAutoDelete(true); // 让线程池自动删除
    // 初始化文件信息
    m_fileInfo = UnifiedFileInfo(filePath);
    // === Martin Fowler修复：统一文件标识生成方法 ===
    // 问题：UnifiedFileInfo::generateFileIdentity() 和 FileIdentityManager::getFileIdentity()
    // 使用不同算法，导致缓存路径不一致
    m_fileInfo.fileIdentity = FileIdentityManager::getFileIdentity(filePath);
    // Martin Fowler重构：DPI配置注入日志
    m_fileInfo.processStatus = FileProcessStatus::Waiting;
    m_fileInfo.progress = 0;
    m_fileInfo.statusText = tr("等待中");
    m_fileInfo.errorMessage = "";
}
FileProcessWorker::~FileProcessWorker()
{
}

void FileProcessWorker::cancel()
{
    QMutexLocker locker(&m_mutex);
    m_cancelled = true;
}

bool FileProcessWorker::isCancelled() const
{
    QMutexLocker locker(const_cast<QMutex*>(&m_mutex));
    return m_cancelled;
}

void FileProcessWorker::run()
{
    // === 关键补充：开始前检查是否已取消 ===
    if (isCancelled()) {
        m_fileInfo.processStatus = FileProcessStatus::Cancelled;
        m_fileInfo.statusText = tr("已取消");
        emit processingFinished(m_fileIndex, false);
        return;
    }
    
    // 更新状态为处理中
    m_fileInfo.processStatus = FileProcessStatus::Processing;
    m_fileInfo.statusText = tr("开始处理");
    emit progressUpdated(m_fileIndex, m_fileInfo);
    
    bool success = false;
    QString fileType = getFileType(m_filePath);
    try {
        if (fileType == "pdf") {
            success = processPDFFile(m_filePath, m_fileInfo);
        } else {
            success = processImageFile(m_filePath, m_fileInfo);
        }
    } catch (const std::exception& e) {
        m_fileInfo.processStatus = FileProcessStatus::Error;
        m_fileInfo.errorMessage = QString("处理异常: %1").arg(e.what());
        m_fileInfo.statusText = tr("处理失败");
        success = false;
    }
    
    // === 关键补充：处理完成前检查是否已取消 ===
    if (isCancelled()) {
        m_fileInfo.processStatus = FileProcessStatus::Cancelled;
        m_fileInfo.statusText = tr("已取消");
        emit processingFinished(m_fileIndex, false);
        return;
    }
    
    // 更新最终状态
    if (success) {
        m_fileInfo.processStatus = FileProcessStatus::Completed;
        m_fileInfo.progress = 100;
        m_fileInfo.statusText = tr("已完成");
    } else {
        m_fileInfo.processStatus = FileProcessStatus::Error;
        m_fileInfo.statusText = tr("处理失败");
    }
    emit progressUpdated(m_fileIndex, m_fileInfo);
    emit processingFinished(m_fileIndex, success);
}
bool FileProcessWorker::processPDFFile(const QString& filePath, UnifiedFileInfo& info)
{
    try {
        // 缓存命中快速路径 - 但需要检查是否为占位符页面
        UnifiedCacheManager* cacheManager = UnifiedCacheManager::instance();
        bool cacheExists = cacheManager && cacheManager->cacheExistsWithPages(filePath);
        if (cacheExists) {
            // 检查第一页是否为占位符页面
            QString fileIdentity = FileIdentityManager::getFileIdentity(filePath);
            QImage firstPage = cacheManager->loadFromCache(fileIdentity, 0);
            // 如果第一页是占位符（小尺寸或包含几何图案），则继续处理真正的PDF
            bool isPlaceholder = false;
            if (firstPage.isNull() || NextGenPlaceholder::isPlaceholder(firstPage)) {
                isPlaceholder = true;
            } else {
                // 检查是否包含占位符的几何图案
                int centerX = firstPage.width() / 2;
                int centerY = firstPage.height() / 2;
                if (detectPlaceholderPattern(firstPage, centerX, centerY)) {
                    isPlaceholder = true;
                }
            }
            if (!isPlaceholder) {
                // 检查DPI是否匹配
                bool dpiMatch = cacheManager->isCacheDpiMatch(filePath, m_dpiConfig.processingDpi);
                if (!dpiMatch) {
                    // DPI不匹配，清除缓存并继续处理
                    cacheManager->clearFileCache(filePath);
                } else {
                    // DPI匹配，使用缓存
                    int pages = cacheManager->getCachedPageCount(filePath);
                    QDateTime latest = cacheManager->getCachedLatestTime(filePath);
                    QString hash = FileIdentityManager::getFileIdentity(filePath);
                    emit metadataReady(m_fileIndex, hash, pages, latest);
                    updateProgress(info, 100, tr("PDF已缓存，跳过处理"));
                    return true;
                }
            } else {
                // 是占位符页面，清除缓存并继续处理
                cacheManager->clearFileCache(filePath);
            }
        }
        // 检查缓存是否已存在（逐页）
        if (cacheManager) {
            // 先尝试加载PDF文档获取页数
            poppler::document* tempDoc = poppler::document::load_from_file(filePath.toStdString());
            if (tempDoc && !tempDoc->is_locked()) {
                int pageCount = tempDoc->pages();
                delete tempDoc;
                bool allCached = true;
                for (int i = 0; i < pageCount; ++i) {
                    QString fileIdentity = FileIdentityManager::getFileIdentity(filePath);
                    if (!cacheManager->isCached(fileIdentity, i)) { allCached = false; break; }
                }
                if (allCached) {
                    // 检查DPI是否匹配
                    bool dpiMatch = cacheManager->isCacheDpiMatch(filePath, m_dpiConfig.processingDpi);
                    if (!dpiMatch) {
                        // DPI不匹配，清除缓存并继续处理
                        cacheManager->clearFileCache(filePath);
                    } else {
                        // DPI匹配，使用缓存
                        int pages = cacheManager->getCachedPageCount(filePath);
                        QDateTime latest = cacheManager->getCachedLatestTime(filePath);
                        QString hash = FileIdentityManager::getFileIdentity(filePath);
                        emit metadataReady(m_fileIndex, hash, pages, latest);
                        updateProgress(info, 100, tr("PDF已缓存，跳过处理"));
                        return true;
                    }
                }
            }
        }
        // 加载PDF文档
        updateProgress(info, 10, tr("加载PDF文档"));
        poppler::document* document = poppler::document::load_from_file(filePath.toStdString());
        if (!document || document->is_locked()) {
            info.setError(tr("PDF文件无法打开或被锁定"));
            return false;
        }
        int pageCount = document->pages();
        info.pageCount = pageCount;
        updateProgress(info, 20, tr("PDF页数: %1").arg(pageCount));
        if (pageCount == 0) {
            info.setError(tr("PDF文件没有页面"));
            delete document;
            return false;
        }
        // 使用新的SystemConfig获取DPI设置
        double dpi = m_dpiConfig.processingDpi;
        updateProgress(info, 30, tr("使用DPI: %1").arg(dpi));
        // 逐页处理 - 优化内存使用
        for (int i = 0; i < pageCount && !m_cancelled; ++i) {
            updateProgress(info, 30 + (i * 60 / pageCount), 
                         tr("处理页面 %1/%2").arg(i + 1).arg(pageCount));
            // 为每一页创建独立的渲染器，处理完后立即释放
            {
                poppler::page_renderer renderer;
                renderer.set_render_hint(poppler::page_renderer::antialiasing, true);
                renderer.set_render_hint(poppler::page_renderer::text_antialiasing, true);
                poppler::page* page = document->create_page(i);
                if (page) {
                    // 直接使用用户设置的DPI，不再根据页面数调整
                    double pageDpi = dpi;
                    poppler::image image = renderer.render_page(page, pageDpi, pageDpi); 
                if (image.is_valid()) {
                    // 保持颜色一致：根据 poppler 格式构造 QImage，不做通道调换
                    const int w = image.width();
                    const int h = image.height();
                    const int stride = image.bytes_per_row();
                    QImage src;
                    switch (image.format()) {
                        case poppler::image::format_rgb24:
                            src = QImage((uchar*)image.data(), w, h, stride, QImage::Format_RGB888);
                            break;
                        case poppler::image::format_bgr24:
#if QT_VERSION >= QT_VERSION_CHECK(6, 6, 0)
                            src = QImage((uchar*)image.data(), w, h, stride, QImage::Format_BGR888);
#else
                            {
                                QImage tmp((uchar*)image.data(), w, h, stride, QImage::Format_RGB888);
                                src = tmp.convertToFormat(QImage::Format_RGB32);
                            }
#endif
                            break;
                        case poppler::image::format_argb32:
                            src = QImage((uchar*)image.data(), w, h, stride, QImage::Format_ARGB32);
                            break;
                        case poppler::image::format_gray8:
                            src = QImage((uchar*)image.data(), w, h, stride, QImage::Format_Grayscale8);
                            break;
                        case poppler::image::format_mono:
                            src = QImage((uchar*)image.data(), w, h, stride, QImage::Format_Mono);
                            break;
                        default:
                            src = QImage((uchar*)image.data(), w, h, stride, QImage::Format_ARGB32);
                            break;
                    }
                    // 合成到白色背景，避免透明导致的偏色；并获得独立内存副本
                    QImage qimage(w, h, QImage::Format_RGB32);
                    qimage.fill(Qt::white);
                    {
                        QPainter painter(&qimage);
                        painter.setRenderHint(QPainter::Antialiasing, true);
                        painter.setRenderHint(QPainter::TextAntialiasing, true);
                        painter.drawImage(0, 0, src);
                    }
                    // === Martin Fowler重构：使用文件级缓存路径保存 ===
                    UnifiedCacheManager* cacheManager = UnifiedCacheManager::instance();
                    if (cacheManager) {
                        bool saveSuccess = cacheManager->saveToCacheWithFileInfo(m_fileInfo, i, qimage, m_dpiConfig.processingDpi);
                    } else {
                    }
                }
                delete page;
            }
            } // 渲染器作用域结束，自动释放内存
            // 强制垃圾回收，释放临时内存
            if (i % 5 == 0) { // 每5页强制清理一次
                QApplication::processEvents();
            }
            // 检查取消状态
            if (m_cancelled) {
                delete document;
                return false;
            }
        }
        delete document;
        updateProgress(info, 95, tr("PDF处理完成"));
        if (cacheManager) {
            int pages = cacheManager->getCachedPageCount(filePath);
            QDateTime latest = cacheManager->getCachedLatestTime(filePath);
            QString hash = FileIdentityManager::getFileIdentity(filePath);
            emit metadataReady(m_fileIndex, hash, pages, latest);
            cacheManager->writeManifest(filePath, pages, latest, QStringLiteral("LongImageReader/1.0"), QString(), m_dpiConfig.processingDpi);
        }
        return true;
    } catch (const std::exception& e) {
        info.setError(QString("PDF处理异常: %1").arg(e.what()));
        return false;
    }
}
bool FileProcessWorker::processImageFile(const QString& filePath, UnifiedFileInfo& info)
{
    // 检查缓存是否已存在（整目录）
    UnifiedCacheManager* cacheManager = UnifiedCacheManager::instance();
    if (cacheManager && cacheManager->cacheExistsWithPages(filePath)) {
        // 检查DPI是否匹配
        bool dpiMatch = cacheManager->isCacheDpiMatch(filePath, m_dpiConfig.processingDpi);
        if (!dpiMatch) {
            // DPI不匹配，清除缓存并继续处理
            cacheManager->clearFileCache(filePath);
        } else {
            // DPI匹配，使用缓存
            int pages = cacheManager->getCachedPageCount(filePath);
            QDateTime latest = cacheManager->getCachedLatestTime(filePath);
            QString hash = FileIdentityManager::getFileIdentity(filePath);
            emit metadataReady(m_fileIndex, hash, pages, latest);
            updateProgress(info, 100, tr("图片已缓存，跳过处理"));
            return true;
        }
    }
    updateProgress(info, 10, tr("检查图片信息"));
    // 先获取图片信息而不加载完整图片
    QImageReader reader(filePath);
    if (!reader.canRead()) {
        info.setError(tr("无法读取图片文件"));
        return false;
    }
    // 获取图片尺寸信息
    QSize imageSize = reader.size();
    if (imageSize.isEmpty()) {
        info.setError(tr("无法获取图片尺寸"));
        return false;
    }
    updateProgress(info, 20, tr("图片尺寸: %1x%2").arg(imageSize.width()).arg(imageSize.height()));
    // 所有图片都使用统一的处理逻辑
    updateProgress(info, 30, tr("开始处理图片"));
    updateProgress(info, 40, tr("加载图片"));
    // 尝试加载图片，如果失败则提供更详细的错误信息
    QImage image;
    try {
        // 放宽内存限制，允许读取超大图片
        reader.setAutoTransform(true);
#if QT_VERSION >= QT_VERSION_CHECK(6, 5, 0)
        reader.setAllocationLimit(0); // 0 表示不限制（Qt6）
#endif
        image = reader.read();
        if (image.isNull()) {
            // 第一次读取失败，记录错误并尝试流式读取
            QString errorString = reader.errorString();
            if (errorString.isEmpty()) {
                errorString = tr("未知错误");
            }
            // 采用统一的分片流式读取，不创建占位符
            QImageReader stripeReader(filePath);
            stripeReader.setAutoTransform(true);
#if QT_VERSION >= QT_VERSION_CHECK(6, 5, 0)
            stripeReader.setAllocationLimit(0);
#endif
            // Martin Fowler重构：使用DPI配置驱动的A4高度计算
            int targetHeight = calculateA4TargetHeight(imageSize.width());
            // 背景色取顶部样本
            QRect sampleRect(0, 0, qMin(imageSize.width(), 1000), qMin(imageSize.height(), 200));
            stripeReader.setClipRect(sampleRect);
            QImage sampleTop = stripeReader.read();
            QColor bgColor = Qt::white;
            if (!sampleTop.isNull()) {
                bgColor = detectBackgroundColor(sampleTop);
            }
            // 复用同一个 reader：清除剪裁窗口，准备条带读取
            stripeReader.setClipRect(QRect());
            stripeReader.setAutoTransform(true);
#if QT_VERSION >= QT_VERSION_CHECK(6, 5, 0)
            stripeReader.setAllocationLimit(0);
#endif
            // 预估分页数量
            int totalPages = (imageSize.height() + targetHeight - 1) / targetHeight;
            // info.pageCount = totalPages; // 不再需要，使用 pageCount
            updateProgress(info, 55, tr("改用流式切片，共 %1 页").arg(totalPages));
            int startY = 0;
            for (int pageIndex = 0; pageIndex < totalPages && !m_cancelled; ++pageIndex) {
                // 在目标高度附近找最佳分割位置
                int bestEndY = findBestSplitPositionStreaming(stripeReader, startY, targetHeight, imageSize, bgColor);
                int currentPageHeight = qMin(bestEndY - startY, imageSize.height() - startY);
                if (currentPageHeight <= 0) {
                    break;
                }
                QRect clipRect(0, startY, imageSize.width(), currentPageHeight);
                stripeReader.setClipRect(clipRect);
                QImage pageImage = stripeReader.read();
                if (pageImage.isNull()) {
                    info.setError(tr("图片第%1页流式读取失败").arg(pageIndex + 1));
                    return false;
                }
                // 填充到目标高度并保存
                QImage paddedPage = createPaddedSlice(pageImage, targetHeight, bgColor);
                bool saveSuccess = cacheManager->saveToCacheWithFileInfo(m_fileInfo, pageIndex, paddedPage, m_dpiConfig.processingDpi);
                if (!saveSuccess) {
                    info.setError(tr("图片第%1页保存到缓存失败").arg(pageIndex + 1));
                    return false;
                }
                startY = bestEndY;
            }
            updateProgress(info, 90, tr("流式切片完成"));
            updateProgress(info, 95, tr("图片处理完成"));
            return true;
        }
    } catch (const std::exception& e) {
        info.setError(tr("图片加载异常: %1").arg(e.what()));
        return false;
    } catch (...) {
        info.setError(tr("图片加载时发生未知异常"));
        return false;
    }
    // 估算处理步骤（基于图片大小）
    int estimatedSteps = 10;
    if (image.width() > 2000 || image.height() > 2000) {
        estimatedSteps = 15;
    }
    // info.totalSteps = estimatedSteps; // 不再需要
    updateProgress(info, 50, tr("开始切片处理"));
    // 图片切片处理
    updateProgress(info, 60, tr("开始图片切片"));
    // 使用智能切割算法进行图片切片处理
    if (cacheManager) {
        updateProgress(info, 65, tr("计算智能切割位置"));
        // 使用智能算法计算分割位置
        QList<int> splitPositions = calculateSplitPositions(image);
        int totalPages = splitPositions.size();
        info.pageCount = totalPages;
        if (totalPages == 0) {
            info.setError(tr("无法计算图片分割位置"));
            return false;
        }
        updateProgress(info, 70, tr("将图片智能分为 %1 页").arg(totalPages));
        // 检测背景色
        QColor bgColor = detectBackgroundColor(image);
        // 逐页切片并保存
        int startY = 0;
        for (int pageIndex = 0; pageIndex < totalPages && !m_cancelled; ++pageIndex) {
            updateProgress(info, 75 + (pageIndex * 15 / totalPages), 
                         tr("智能处理第 %1/%2 页").arg(pageIndex + 1).arg(totalPages));
            // 计算当前页的裁剪区域
            int endY = splitPositions[pageIndex];
            int currentPageHeight = endY - startY;
            QRect cropRect(0, startY, image.width(), currentPageHeight);
            QImage pageImage = image.copy(cropRect);
            if (!pageImage.isNull()) {
                // Martin Fowler重构：使用DPI配置驱动的A4高度计算
                int targetHeight = calculateA4TargetHeight(image.width());
                QImage paddedPage = createPaddedSlice(pageImage, targetHeight, bgColor);
                // 保存页面到缓存
                bool saveSuccess = cacheManager->saveToCacheWithFileInfo(m_fileInfo, pageIndex, paddedPage, m_dpiConfig.processingDpi);
                if (saveSuccess) {
                } else {
                    info.setError(tr("图片第%1页保存到缓存失败").arg(pageIndex + 1));
                    return false;
                }
            } else {
                // 如果页面切片失败，直接报错
                info.setError(tr("图片第%1页切片失败").arg(pageIndex + 1));
                return false;
            }
            startY = endY;
            // 检查取消状态
            if (m_cancelled) {
                return false;
            }
        }
        updateProgress(info, 90, tr("智能图片切片完成，共 %1 页").arg(totalPages));
    }
    updateProgress(info, 95, tr("图片处理完成"));
    if (cacheManager) {
        int pages = cacheManager->getCachedPageCount(filePath);
        QDateTime latest = cacheManager->getCachedLatestTime(filePath);
        QString hash = FileIdentityManager::getFileIdentity(filePath);
        emit metadataReady(m_fileIndex, hash, pages, latest);
        cacheManager->writeManifest(filePath, pages, latest, QStringLiteral("LongImageReader/1.0"), QString(), m_dpiConfig.processingDpi);
    }
    return true;
}
void FileProcessWorker::updateProgress(UnifiedFileInfo& info, int progress, const QString& statusText)
{
    QMutexLocker locker(&m_mutex);
    info.updateProgress(progress, statusText);
    emit progressUpdated(m_fileIndex, info);
}
QString FileProcessWorker::getFileType(const QString& filePath)
{
    QFileInfo fileInfo(filePath);
    QString suffix = fileInfo.suffix().toLower();
    if (suffix == "pdf") {
        return "pdf";
    } else if (QImageReader::supportedImageFormats().contains(suffix.toLocal8Bit())) {
        return "image";
    }
    return "unknown";
}
// 智能图片切割相关方法实现
QColor FileProcessWorker::detectBackgroundColor(const QImage& image)
{
    // 安全检查：确保图像有效且尺寸足够
    if (image.isNull() || image.width() <= 0 || image.height() <= 0) {
        return QColor(255, 255, 255); // 返回白色作为默认背景色
    }
    // 使用角落和邊緣的像素來檢測背景色，添加边界检查
    QList<QColor> samples;
    // 安全地获取角落像素，确保坐标在有效范围内
    if (image.width() > 0 && image.height() > 0) {
        samples << QColor(image.pixel(0, 0));
    }
    if (image.width() > 1 && image.height() > 0) {
        samples << QColor(image.pixel(image.width()-1, 0));
    }
    if (image.width() > 0 && image.height() > 1) {
        samples << QColor(image.pixel(0, image.height()-1));
    }
    if (image.width() > 1 && image.height() > 1) {
        samples << QColor(image.pixel(image.width()-1, image.height()-1));
    }
    if (image.width() > 2 && image.height() > 0) {
        samples << QColor(image.pixel(image.width()/2, 0));
    }
    if (image.width() > 2 && image.height() > 1) {
        samples << QColor(image.pixel(image.width()/2, image.height()-1));
    }
    // 如果没有成功获取到任何样本，返回白色
    if (samples.isEmpty()) {
        return QColor(255, 255, 255);
    }
    // 計算平均顏色
    int r = 0, g = 0, b = 0;
    for (const QColor& color : samples) {
        r += color.red();
        g += color.green();
        b += color.blue();
    }
    return QColor(r/samples.size(), g/samples.size(), b/samples.size());
}
bool FileProcessWorker::isEmptyRow(const QImage& image, int y, const QColor& bgColor, int threshold)
{
    // 安全检查：确保图像有效且y坐标在有效范围内
    if (image.isNull() || y < 0 || y >= image.height() || image.width() <= 0) {
        return false;
    }
    int emptyPixels = 0;
    int totalSamples = 0;
    // 每4個像素採樣一次以提高性能，但要确保不越界
    for (int x = 0; x < image.width(); x += 4) {
        // 确保 x 坐标不越界
        if (x >= image.width()) {
            break;
        }
        QColor pixelColor(image.pixel(x, y));
        totalSamples++;
        if (qAbs(pixelColor.red() - bgColor.red()) <= threshold &&
            qAbs(pixelColor.green() - bgColor.green()) <= threshold &&
            qAbs(pixelColor.blue() - bgColor.blue()) <= threshold) {
            emptyPixels++;
        }
    }
    // 避免除以零的错误
    if (totalSamples == 0) {
        return false;
    }
    // 如果超過95%的採樣像素是背景色，認為是空行
    int emptyPercentage = (emptyPixels * 100) / totalSamples;
    return emptyPercentage > 95;
}
int FileProcessWorker::findBestSplitPosition(const QImage& image, int startY, 
                                        int targetHeight, const QColor& bgColor)
{
    // 首先在目標高度之前搜索（優先選擇較短的切片）
    int searchStart = qMax(startY + targetHeight - 100, startY);  // 向上搜索100像素
    int searchEnd = qMin(startY + targetHeight, image.height());  // 目標高度，但不超过图像边界
    int bestPosition = qMin(startY + targetHeight, image.height());  // 默認位置，但不超过图像边界
    int maxEmptyRows = 0;
    int currentEmptyRows = 0;
    // 首先在目標高度之前搜索
    for (int y = searchStart; y < searchEnd; ++y) {
        if (isEmptyRow(image, y, bgColor)) {
            currentEmptyRows++;
            if (currentEmptyRows > maxEmptyRows) {
                maxEmptyRows = currentEmptyRows;
                bestPosition = y - currentEmptyRows / 2;  // 取空白區域的中間
            }
        } else {
            currentEmptyRows = 0;
        }
    }
    // 如果在目標高度之前沒有找到合適的分割點，才考慮向後搜索
    if (maxEmptyRows == 0 && searchEnd < image.height()) {
        int extendedSearchEnd = qMin(searchEnd + 50, image.height());  // 最多向後搜索50像素
        currentEmptyRows = 0;
        for (int y = searchEnd; y < extendedSearchEnd; ++y) {
            if (isEmptyRow(image, y, bgColor)) {
                currentEmptyRows++;
                if (currentEmptyRows > maxEmptyRows) {
                    maxEmptyRows = currentEmptyRows;
                    bestPosition = y - currentEmptyRows / 2;
                }
            } else {
                currentEmptyRows = 0;
            }
        }
    }
    // 如果完全沒找到空行，就使用目標高度
    if (maxEmptyRows == 0) {
        bestPosition = qMin(startY + targetHeight, image.height());
    }
    // 防止无限循环的额外检查
    if (bestPosition <= startY) {
        bestPosition = qMin(startY + targetHeight, image.height());  // 强制前进目标高度，但不超过边界
    }
    // 确保不会超出图片边界
    if (bestPosition >= image.height()) {
        bestPosition = image.height();
    }
    return bestPosition;
}
QList<int> FileProcessWorker::calculateSplitPositions(const QImage& image)
{
    QList<int> splitPositions;
    if (image.isNull()) {
        return splitPositions;
    }
    // 檢測背景色
    QColor bgColor = detectBackgroundColor(image);
    // Martin Fowler重构：使用DPI配置驱动的A4高度计算
    int a4Height = calculateA4TargetHeight(image.width());
    // 預計算所有分割位置
    int y = 0;
    int splitCount = 0;
    while (y < image.height()) {
        // 尋找最佳分割位置
        int splitPos = findBestSplitPosition(image, y, a4Height, bgColor);
        splitPositions.append(splitPos);
        splitCount++;
        // 防止无限循环
        if (splitPos <= y) {
            break;
        }
        y = splitPos;
        // 防止计算过多分割点（调试用）
        if (splitCount > 100) {
            break;
        }
    }
    return splitPositions;
}
QImage FileProcessWorker::createPaddedSlice(const QImage& source, int targetHeight, 
                                       const QColor& bgColor)
{
    QImage result(source.width(), targetHeight, QImage::Format_RGB32);
    result.fill(bgColor);
    // 將源圖像繪製到結果圖像上
    QPainter painter(&result);
    painter.drawImage(0, 0, source);
    return result;
}
int FileProcessWorker::findBestSplitPositionStreaming(QImageReader& reader,
                                       int startY,
                                       int targetHeight,
                                       const QSize& imageSize,
                                       const QColor& bgColor)
{
    // 在 startY+targetHeight 附近读取一个窗口（向上100，向下50）
    int desiredY = startY + targetHeight;
    int windowTop = qMax(startY, desiredY - 120);
    int windowBottom = qMin(imageSize.height(), desiredY + 60);
    int windowHeight = windowBottom - windowTop;
    if (windowHeight <= 0) {
        return qMin(desiredY, imageSize.height());
    }
    QRect clipRect(0, windowTop, imageSize.width(), windowHeight);
    reader.setClipRect(clipRect);
    QImage windowImg = reader.read();
    if (windowImg.isNull()) {
        // 读取窗口失败，退回目标高度
        return qMin(desiredY, imageSize.height());
    }
    // 在窗口内寻找最佳空行，转换到全图坐标
    int localSearchStart = qMax(0, desiredY - 100 - windowTop);
    int localSearchEnd = qMin(windowImg.height(), desiredY - windowTop);
    int bestLocal = targetHeight; // 默认位置（相对 startY）
    int maxEmptyRows = 0;
    int currentEmpty = 0;
    // 优先向上搜索
    for (int y = localSearchStart; y < localSearchEnd; ++y) {
        if (isEmptyRow(windowImg, y, bgColor)) {
            currentEmpty++;
            if (currentEmpty > maxEmptyRows) {
                maxEmptyRows = currentEmpty;
                bestLocal = (windowTop + y) - startY - currentEmpty / 2;
            }
        } else {
            currentEmpty = 0;
        }
    }
    // 如果没找到，再向下补充搜索 50px
    if (maxEmptyRows == 0) {
        currentEmpty = 0;
        int downStart = localSearchEnd;
        int downEnd = qMin(windowImg.height(), downStart + 50);
        for (int y = downStart; y < downEnd; ++y) {
            if (isEmptyRow(windowImg, y, bgColor)) {
                currentEmpty++;
                if (currentEmpty > maxEmptyRows) {
                    maxEmptyRows = currentEmpty;
                    bestLocal = (windowTop + y) - startY - currentEmpty / 2;
                }
            } else {
                currentEmpty = 0;
            }
        }
    }
    int finalPos = startY + (maxEmptyRows == 0 ? targetHeight : qBound(1, bestLocal, targetHeight + 50));
    finalPos = qMin(finalPos, imageSize.height());
    if (finalPos <= startY) {
        finalPos = qMin(startY + targetHeight, imageSize.height());
    }
    return finalPos;
}
bool FileProcessWorker::detectPlaceholderPattern(const QImage& image, int centerX, int centerY) const
{
    // 检测美观占位符的几何图案特征
    int width = image.width();
    int height = image.height();
    // 检测同心圆图案
    bool hasConcentricCircles = false;
    for (int radius = 60; radius <= 150; radius += 30) {
        if (centerX - radius >= 0 && centerX + radius < width &&
            centerY - radius >= 0 && centerY + radius < height) {
            // 检查圆周上的像素是否具有圆形特征
            int circlePixels = 0;
            int totalCirclePixels = 0;
            for (int angle = 0; angle < 360; angle += 10) {
                double rad = angle * M_PI / 180.0;
                int x = centerX + radius * qCos(rad);
                int y = centerY + radius * qSin(rad);
                if (x >= 0 && x < width && y >= 0 && y < height) {
                    QColor pixel = image.pixelColor(x, y);
                    int brightness = (pixel.red() + pixel.green() + pixel.blue()) / 3;
                    // 检查是否为灰色（占位符特征）
                    if (brightness > 120 && brightness < 180) {
                        circlePixels++;
                    }
                    totalCirclePixels++;
                }
            }
            if (totalCirclePixels > 0 && (double)circlePixels / totalCirclePixels > 0.7) {
                hasConcentricCircles = true;
                break;
            }
        }
    }
    // 检测装饰性线条
    bool hasDecorativeLines = false;
    int linePixels = 0;
    int totalLinePixels = 0;
    // 检查对角线
    for (int i = 0; i < 200; i += 5) {
        int x1 = centerX - 100 + i;
        int y1 = centerY - 100 + i;
        int x2 = centerX + 100 - i;
        int y2 = centerY + 100 - i;
        if (x1 >= 0 && x1 < width && y1 >= 0 && y1 < height) {
            QColor pixel = image.pixelColor(x1, y1);
            int brightness = (pixel.red() + pixel.green() + pixel.blue()) / 3;
            if (brightness > 100 && brightness < 200) {
                linePixels++;
            }
            totalLinePixels++;
        }
        if (x2 >= 0 && x2 < width && y2 >= 0 && y2 < height) {
            QColor pixel = image.pixelColor(x2, y2);
            int brightness = (pixel.red() + pixel.green() + pixel.blue()) / 3;
            if (brightness > 100 && brightness < 200) {
                linePixels++;
            }
            totalLinePixels++;
        }
    }
    if (totalLinePixels > 0 && (double)linePixels / totalLinePixels > 0.6) {
        hasDecorativeLines = true;
    }
    return hasConcentricCircles || hasDecorativeLines;
}
// Martin Fowler重构：DPI配置驱动的A4高度计算
int FileProcessWorker::calculateA4TargetHeight(int imageWidth) const
{
    // 使用DPI配置计算A4比例，替代硬编码
    QSize a4Size = getCurrentA4Size();
    double a4Ratio = static_cast<double>(a4Size.height()) / a4Size.width();
    int targetHeight = static_cast<int>(imageWidth * a4Ratio);
    if (targetHeight <= 0) {
        targetHeight = 1000; // 安全回退值
    }
    return targetHeight;
}
